package 多线程.Test.yuyinTest;

import java.util.Arrays;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ParallelArrayProcessor {

    // 线程池配置
    private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    private static final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

    /**
     * 处理数组元素，每个元素乘以10
     * @param input 输入数组
     * @return 处理后的数组，保持原始顺序
     */
    public static int[] processArray(int[] input) {
        if (input == null || input.length == 0) {
            return new int[0];
        }

        // 结果数组
        int[] result = new int[input.length];
        
        // 使用CountDownLatch等待所有任务完成
        CountDownLatch latch = new CountDownLatch(input.length);
        
        // 为每个数组元素创建处理任务
        for (int i = 0; i < input.length; i++) {
            final int index = i;
            executor.submit(() -> {
                try {
                    // 带重试的处理逻辑
                    result[index] = processWithRetry(input[index], 3);
                } catch (Exception e) {
                    System.err.printf("处理元素 %d (值: %d) 失败，重试次数用尽: %s%n",
                            index, input[index], e.getMessage());
                    result[index] = -1; // 用-1表示处理失败
                } finally {
                    latch.countDown();
                }
            });
        }

        // 等待所有任务完成
        try {
            latch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("主线程被中断", e);
        }

        return result;
    }

    /**
     * 带重试的处理逻辑
     * @param value 要处理的值
     * @param maxRetries 最大重试次数
     * @return 处理结果
     * @throws Exception 重试次数用尽后抛出异常
     */
    private static int processWithRetry(int value, int maxRetries) throws Exception {
        AtomicInteger retryCount = new AtomicInteger(0);
        Exception lastException = null;

        while (retryCount.get() < maxRetries) {
            try {
                // 模拟可能失败的操作
                return multiplyByTen(value);
            } catch (Exception e) {
                lastException = e;
                retryCount.incrementAndGet();
                System.err.printf("处理值 %d 失败 (尝试 %d/%d): %s%n",
                        value, retryCount.get(), maxRetries, e.getMessage());
                
                // 指数退避等待
                try {
                    Thread.sleep((long) Math.pow(2, retryCount.get()) * 100);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("重试等待被中断", ie);
                }
            }
        }

        throw new Exception("重试次数用尽", lastException);
    }

    /**
     * 乘以10的操作（模拟可能失败）
     * @param value 输入值
     * @return 乘以10的结果
     * @throws Exception 模拟可能发生的异常
     */
    private static int multiplyByTen(int value) throws Exception {
        // 模拟10%的失败率
        if (Math.random() < 0.1) {
            throw new Exception("随机模拟的运算失败");
        }
        
        // 模拟处理耗时
        Thread.sleep(10 + (long)(Math.random() * 50));
        return value * 10;
    }

    // 关闭线程池
    public static void shutdown() {
        executor.shutdown();
        try {
            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    public static void main(String[] args) {
        int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        
        System.out.println("输入数组: " + Arrays.toString(input));
        
        int[] result = processArray(input);
        
        System.out.println("输出数组: " + Arrays.toString(result));
        
        shutdown();
    }
}